<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Chapter&nbsp;18.&nbsp;工作流的测试驱动开发（TDD）</title>
    <link rel="stylesheet" href="css/html.css" type="text/css">
    <meta name="generator" content="DocBook XSL Stylesheets V1.65.1">
    <link rel="home" href="index.html" title="JBoss jBPM 3.1">
    <link rel="up" href="index.html" title="JBoss jBPM 3.1">
    <link rel="previous" href="security.html" title="Chapter&nbsp;17.&nbsp;Security">
    <link rel="next" href="pluggable.html" title="Chapter&nbsp;19.&nbsp;Pluggable architecture">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
    <table width="100%" summary="Navigation header">
        <tr>
            <th colspan="3" align="center">Chapter&nbsp;18.&nbsp;工作流的测试驱动开发（TDD）</th>
        </tr>
        <tr>
            <td width="20%" align="left"><a accesskey="p" href="security.html">Prev</a>&nbsp;</td>
            <th width="60%" align="center">&nbsp;</th>
            <td width="20%" align="right">&nbsp;<a accesskey="n" href="pluggable.html">Next</a></td>
        </tr>
    </table>
    <hr>
</div>
<div class="chapter" lang="cn">
    <div class="titlepage">
        <div>
            <div><h2 class="title"><a name="tdd"></a>Chapter&nbsp;18.&nbsp;工作流的测试驱动开发（TDD）</h2></div>
        </div>
        <div></div>
    </div>
    <div class="section" lang="cn">
        <div class="titlepage">
            <div>
                <div><h2 class="title" style="clear: both"><a name="intoducingtddforworkflow"></a>18.1.&nbsp;把测试驱动开发(TDD)带入工作流</h2></div>
            </div>
            <div></div>
        </div>
        <p>Since developing process oriented software is no different from
            developing any other software, we believe that process definitions should
            be easily testable. This chapter shows how you can use plain JUnit without
            any extensions to unit test the process definitions that you author.</p>

        <p>The development cycle should be kept as short as possible. Changes
            made to the sources of software should be immediately verifiable. Preferably,
            without any intermediate build steps. The examples given below will show
            you how to develop and test jBPM processes without intermediate steps.</p>

        <p>Mostly the unit tests of process definitions are execution scenarios.
            Each scenario is executed in one JUnit testmethod and will feed in the external
            triggers (read: signals) into a process execution and verifies after each signal
            if the process is in the expected state.</p>

        <p>Let's look at an example of such a test. We take a simplified version of
            the auction process with the following graphical representation:</p>

        <div class="figure"><a name="auction.test.image"></a>

            <div class="mediaobject" align="center"><img src="images/auction.test.gif" align="middle"
                                                         alt="The auction test process"></div>
            <p class="title"><b>Figure&nbsp;18.1.&nbsp;The auction test process</b></p></div>
        <p>Now, let's write a test that executes the main scenario:</p><pre class="programlisting">public class AuctionTest extends TestCase {

  // parse the process definition
  static ProcessDefinition auctionProcess = 
      ProcessDefinition.parseParResource("org/jbpm/tdd/auction.par");

  // get the nodes for easy asserting
  static StartState start = auctionProcess.getStartState();
  static State auction = (State) auctionProcess.getNode("auction");
  static EndState end = (EndState) auctionProcess.getNode("end");

  // the process instance
  ProcessInstance processInstance;

  // the main path of execution
  Token token;

  public void setUp() {
    // create a new process instance for the given process definition
    processInstance = new ProcessInstance(auctionProcess);

    // the main path of execution is the root token
    token = processInstance.getRootToken();
  }
  
  public void testMainScenario() {
    // after process instance creation, the main path of 
    // execution is positioned in the start state.
    assertSame(start, token.getNode());
    
    token.signal();
    
    // after the signal, the main path of execution has 
    // moved to the auction state
    assertSame(auction, token.getNode());
    
    token.signal();
    
    // after the signal, the main path of execution has 
    // moved to the end state and the process has ended
    assertSame(end, token.getNode());
    assertTrue(processInstance.hasEnded());
  }
}</pre>
    </div>
    <div class="section" lang="cn">
        <div class="titlepage">
            <div>
                <div><h2 class="title" style="clear: both"><a name="xmlsources"></a>18.2.&nbsp;XML 源文件</h2></div>
            </div>
            <div></div>
        </div>
        <p>Before you can start writing execution scenario's, you need a
            <tt class="literal">ProcessDefinition</tt>. The easiest way to get a
            <tt class="literal">ProcessDefinition</tt> object is by parsing xml. If you
            have code completion, type <tt class="literal">ProcessDefinition.parse</tt>
            and activate code completion. Then you get the various parsing methods.
            There are basically 3 ways to write xml that can be parsed to a
            <tt class="literal">ProcessDefinition</tt> object:</p>

        <div class="section" lang="cn">
            <div class="titlepage">
                <div>
                    <div><h3 class="title"><a name="parsingaprocessarchive"></a>18.2.1.&nbsp;Parsing a process archive
                    </h3></div>
                </div>
                <div></div>
            </div>
            <p>A process archive is a zip file that contains the process xml
                in a file called <tt class="literal">processdefinition.xml</tt>. The jBPM
                process designer reads and writes process archives. For example:</p><pre class="programlisting">...
static ProcessDefinition auctionProcess = 
    ProcessDefinition.parseParResource("org/jbpm/tdd/auction.par");
...</pre>
        </div>
        <div class="section" lang="cn">
            <div class="titlepage">
                <div>
                    <div><h3 class="title"><a name="parsinganxmlfile"></a>18.2.2.&nbsp;Parsing an xml file</h3></div>
                </div>
                <div></div>
            </div>
            <p>In other situations, you might want to write the
                processdefinition.xml file by hand and later package the zip file
                with e.g. an ant script. In that case, you can use the
                <tt class="literal">JpdlXmlReader</tt></p><pre class="programlisting">...
static ProcessDefinition auctionProcess = 
    ProcessDefinition.parseXmlResource("org/jbpm/tdd/auction.xml");
...</pre>
        </div>
        <div class="section" lang="cn">
            <div class="titlepage">
                <div>
                    <div><h3 class="title"><a name="parsinganxmlstring"></a>18.2.3.&nbsp;Parsing an xml String</h3>
                    </div>
                </div>
                <div></div>
            </div>
            <p>The simplest option is to parse the xml in the unit test
                inline from a plain String.</p><pre class="programlisting">...
static ProcessDefinition auctionProcess = 
    ProcessDefinition.parseXmlString(
  "&lt;process-definition&gt;" + 
  "  &lt;start-state name='start'&gt;" + 
  "    &lt;transition to='auction'/&gt;" + 
  "  &lt;/start-state&gt;" + 
  "  &lt;state name='auction'&gt;" + 
  "    &lt;transition to='end'/&gt;" + 
  "  &lt;/state&gt;" + 
  "  &lt;end-state name='end'/&gt;" + 
  "&lt;/process-definition&gt;");
...</pre>
        </div>
    </div>
    <div class="section" lang="cn">
        <div class="titlepage">
            <div>
                <div><h2 class="title" style="clear: both"><a name="testingsubprocesses"></a>18.3.&nbsp;测试子流程</h2></div>
            </div>
            <div></div>
        </div>
        <p>TODO (see test/java/org/jbpm/graph/exe/ProcessStateTest.java)</p></div>
</div>
<div class="navfooter">
    <hr>
    <table width="100%" summary="Navigation footer">
        <tr>
            <td width="40%" align="left"><a accesskey="p" href="security.html">Prev</a>&nbsp;</td>
            <td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td>
            <td width="40%" align="right">&nbsp;<a accesskey="n" href="pluggable.html">Next</a></td>
        </tr>
        <tr>
            <td width="40%" align="left" valign="top">Chapter&nbsp;17.&nbsp;Security&nbsp;</td>
            <td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td>
            <td width="40%" align="right" valign="top">&nbsp;Chapter&nbsp;19.&nbsp;可插入架构</td>
        </tr>
    </table>
</div>
</body>
</html>